6 typedef unsigned int uint
;
7 typedef unsigned long long int uint64
;
9 #define forsn(i, s, n) for (uint i = (s); i < (n); i++)
10 #define forn(i, n) forsn (i, 0, n)
12 #define num_diagonals(n) (2 * (n) - 1)
14 typedef vector
<uint64
> vuint64
;
15 typedef vector
<vuint64
> vvuint64
;
19 // m: output matrix, should have 2 rows and k + 1 columns
20 // black_white == 1 iff we are dealing with the white cells and an odd value of n
21 vuint64
*put_bishops_monochrome(uint n
, uint k
, bool black_white
, vvuint64
& m
) {
24 m
[0][0] = 1; // we can always put 0 bishops
27 forn (i
, n
- black_white
) {
28 uint num_cells
= 2 * (i
/ 2) + 1 + black_white
;
30 m
[row
][j
] = m
[!row
][j
] + m
[!row
][j
- 1] * (num_cells
- (j
- 1));
37 uint64
put_bishops(uint n
, uint k
) {
39 if (k
== 1 && n
== 1) return 1;
40 if (k
> num_diagonals(n
) - 1) return 0;
42 vvuint64
matrix_black(2, vuint64(k
+ 1, 0));
43 vvuint64
matrix_white(2, vuint64(k
+ 1, 0));
45 vuint64
& black(*put_bishops_monochrome(n
, k
, BLACK
, matrix_black
));
46 vuint64
& white(n
% 2 == 0 ? black
: *put_bishops_monochrome(n
, k
, WHITE
, matrix_white
));
49 uint lower
= k
> (n
- 1) ? k
- (n
- 1) : 0;
50 uint upper
= min(k
, n
- 1) + 1;
51 forsn (a
, lower
, upper
) {
52 ways
+= black
[a
] * white
[k
- a
];
60 scanf("%u %u", &n
, &k
);
61 if (n
== 0 && k
== 0) break;
62 cout
<< put_bishops(n
, k
) << endl
;